package com.batsoft.redis;

import com.batsoft.redis.utils.SerializeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

/**
 * @author <a href="mailto:HelloHeSir@gmail.com">Mr_He</a>
 */
@Service("redisCluster")
public class RedisClusterImpl implements RedisCluster {

    private final JedisCluster jedis;

    @Autowired
    public RedisClusterImpl(JedisCluster jedis) {
        this.jedis = jedis;
    }

    @Override
    public void set(String key, String value, int time) {
        try {
            jedis.set(key, value);
            jedis.expire(key, time);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void set(String key, String value) {
        try {
            jedis.set(key, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public String get(String key) {
        try {
            return jedis.get(key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void incr(String key) {
        try {
            jedis.incr(key);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void del(String key) {
        try {
            jedis.del(key);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 匹配所有节点的keys并组装
     */
    @Override
    public Set<String> keys(String pattern) {
        TreeSet<String> keys = new TreeSet<>();
        Map<String, JedisPool> clusterNodes = jedis.getClusterNodes();

        for (String key : clusterNodes.keySet()) {
            JedisPool jedisPool = clusterNodes.get(key);
            try (Jedis jedisConn = jedisPool.getResource()) {
                keys.addAll(jedisConn.keys(pattern));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return keys;
    }

    @Override
    public Set<String> values(String pattern) {
        try {
            Set<String> keys = keys(pattern);
            Set<String> set = new HashSet<String>();
            for (String key : keys) {
                set.add(jedis.get(key));
            }
            return set;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public int keySize(String pattern) {
        try {
            return keys(pattern).size();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    @Override
    public void delAll(String pattern) {
        try {
            Set<String> keys = keys(pattern);
            for (String key : keys) {
                jedis.del(key);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public <T> T getObj(String key) {
        try {
            return (T) SerializeUtil.unserialize(jedis.get(key.getBytes()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void setObj(String key, Object value) {
        try {
            jedis.set(key.getBytes(), SerializeUtil.serialize(value));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}